#!/usr/bin/python
###
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# VideoArea and VideoWidget from Listen
# Listen is the legal property of mehdi abaakouk <theli48@gmail.com>
# Copyright (c) 2006 Mehdi Abaakouk
###

try:
 	import pygtk
  	pygtk.require("2.0")
except:
  	pass
try:
	import gtk
  	import gobject
  	import gtk.glade
except:
	sys.exit(1)

import os
#from mplayer import *
import pygst
pygst.require("0.10")
import gst

class Gui:
#gst-launch-0.10 -vvv udpsrc uri=udp://239.3.1.3:1234 ! audio/mpeg ! queue ! \
#{ tcpserversink host=192.168.2.1 port=1234 }
    def __init__(self):
        self.statuses = {'buffer':'','pos':'00:00','dur':'00:00'}
        self._query_id = -1
        self.cur_index = -1
        self.paused = False
        self.count = 0
        self.seeking = False # User is seeking, stop updating seeker from timer
        self.update_seeker = False # Update seeker to current position, from timer
        self.can_seek = False
        self.metadata = {} #Tags
        
        #Set the Glade file
        self.gladefile = "ytube/gui/gui.glade"  
        self.wTree = gtk.glade.XML(self.gladefile)
        #Get the Main Window, and connect the "destroy" event
        self.window = self.wTree.get_widget("window")
        if (self.window):
            self.window.connect("destroy", self.destroy)
        
        self.treeview = self.wTree.get_widget("treeview1")
        self.vboxplayer = self.wTree.get_widget("vboxplayer")
        self.status = self.wTree.get_widget("status")
        self.seeker = self.wTree.get_widget("seeker")
        self.vwidget = VideoWidget(self)
        self.vwidget.show_all()
        self.vboxplayer.pack_start(self.vwidget)
        
        self.player = gst.Pipeline("player")
        self.source = gst.element_factory_make("filesrc", "data-source")
        self.source.set_property("location","/home/furyy/Videod/monstersvsaliens-tlr2_h720p.mov")
        self.decoder = gst.element_factory_make("decodebin", "decoder")
        self.decoder.connect("pad-added", self.decoder_callback)

        self.videosink = gst.element_factory_make("gconfvideosink", "video-sink")
        self.audiosink = gst.element_factory_make("autoaudiosink", "audio-output")
        self.audiocaps = gst.element_factory_make("capsfilter", "audio-caps")
        self.audiocaps.set_property('caps', gst.caps_from_string('audio/x-raw-int,rate=44100,width=16,depth=16'))
        
        self.audioconv = gst.element_factory_make("audioconvert", "aconverter")
        self.audioresample = gst.element_factory_make("audioresample", "aresample")
        self.ffmpeg1 = gst.element_factory_make("ffmpegcolorspace", "ffmpeg1")

        self.queuea = gst.element_factory_make("queue", "queuea")
        self.queuev = gst.element_factory_make("queue", "queuev")
        
        self.player.add(self.source, self.queuea, self.ffmpeg1,self.queuev,self.decoder,self.videosink, self.audiosink,self.audioconv,self.audiocaps,self.audioresample)
        
        gst.element_link_many(self.source,self.decoder)
        gst.element_link_many(self.queuea,self.audioconv,self.audioresample,self.audiocaps,self.audiosink)
        gst.element_link_many(self.queuev,self.ffmpeg1,self.videosink)  
        
        bus = self.player.get_bus()
        bus.add_signal_watch()
        bus.enable_sync_message_emission()
        bus.connect("message", self.on_message)
        bus.connect("message::tag", self.on_tag_message)
        bus.connect("sync-message::element", self.on_sync_message)
        
        self.player.set_state(gst.STATE_PLAYING)

        self.time_format = gst.Format(gst.FORMAT_TIME)
        self.time_format_percent = gst.Format(gst.FORMAT_PERCENT)
        self.time_format_bytes = gst.Format(gst.FORMAT_BYTES)


    def decoder_callback(self, decoder, pad):
        structure_name = pad.get_caps()[0].get_name()
        print structure_name
        #print pad.get_property("template").name_template
        if structure_name.startswith("video"):
            queuev_pad = self.queuev.get_pad("sink")
            pad.link(queuev_pad)
            #gst.element_link_many(self.queuev,self.ffmpeg1,self.videosink)  
        elif structure_name.startswith("audio"):
            queuea_pad = self.queuea.get_pad("sink")
            pad.link(queuea_pad)
            #gst.element_link_many(self.queuea,self.audioconv,self.audioresample,self.audiocaps,self.audiosink)

    def demuxer_callback(self, demuxer, pad):
        print pad.get_property("template").name_template
        if pad.get_property("template").name_template == "video_%02d":
            queuev_pad = self.queuev.get_pad("sink")
            pad.link(queuev_pad)
            
        elif pad.get_property("template").name_template == "audio_%02d":
            queuea_pad = self.queuea.get_pad("sink")
            pad.link(queuea_pad)
            
    def muxer_callback(self, muxer, pad):
        print pad.get_property("template").name_template
        #if pad.get_property("template").name_template == "video_%02d":
        #    queuev_pad = self.queuev.get_pad("sink")
        #    pad.link(queuev_pad)
        #elif pad.get_property("template").name_template == "audio_%02d":
        #    queuea_pad = self.queuea.get_pad("sink")
        #    pad.link(queuea_pad)
            
    def get_duration_ns(self):
        return self.player.query_duration(self.time_format, None)[0]
        
    def get_duration(self):
        return self.get_duration_ns() / 1000000000
        
    def get_duration_bytes(self):
        return self.player.query_duration(self.time_format_bytes, None)[0]
    
    def get_position_ns(self):
        return self.player.query_position(self.time_format, None)[0]

    def get_position_bytes(self):
        return self.player.query_position(self.time_format_bytes, None)[0]
        
    def on_vol_changed(self,w):
        self.set_vol(w.get_value())
    
    def set_vol(self,vol = None):
        self.player.set_property("volume",vol)
    
    def on_tag_message(self, bus, message):
        tags = message.parse_tag()
        for x in tags.keys():
            print x,"=",tags[x]
            if x != "private-id3v2-frame":
                self.metadata[x] = tags[x]
    
    def on_message(self, bus, message):
        
        t = message.type
        #print "Message of",t
        if t == gst.MESSAGE_EOS:
            self.player.set_state(gst.STATE_NULL)
            print "EOS"
            
        elif t == gst.MESSAGE_ERROR:
            self.player.set_state(gst.STATE_NULL)
            err, debug = message.parse_error()
            print "Error: %s" % err, debug
            print message
            self.destroy(None)
        #elif t == gst.MESSAGE_TAG:
        #    tags = message.parse_tag()
        #    for x in tags.keys():
        #        print x,"=",tags[x]
            
        elif t == gst.MESSAGE_BUFFERING:
            self.statuses['buffer'] = "%d%%"%message.parse_buffering()
            self.set_status()
            
        elif t == gst.MESSAGE_STATE_CHANGED:
            old,new,pending = message.parse_state_changed()
        '''
            if new == gst.STATE_PLAYING:
                pos_int = self.get_duration_ns()
                
		if pos_int > -1:
                    self.statuses['dur'] = self.convert_ns(pos_int)
                    self.can_seek = True
		else:
                    self.statuses['dur'] = '00:00'
                    self.can_seek = False
		

                self.set_status()
                self.set_vol()
                self.set_tree_file_length(self.statuses['dur'])
            elif old == gst.STATE_NULL:
                self.statuses = {'buffer':'','pos':'00:00','dur':'00:00'}
                self.set_status()
        '''
    def on_sync_message(self, bus, message):
        if message.structure is None:
            return
        message_name = message.structure.get_name()
        if message_name == "prepare-xwindow-id":
            imagesink = message.src
            imagesink.set_property("force-aspect-ratio", True)
            self.vwidget.set_sink(imagesink)
            

    def on_start_pause(self,w):
        
        if self.player.get_state()[1] != gst.STATE_NULL:
            if self.player.get_state()[1] == gst.STATE_PLAYING:
                self.set_play_play()
                self.player.set_state(gst.STATE_PAUSED)
                self.paused = True
            else:
                self.player.set_state(gst.STATE_PLAYING)
                self.set_play_pause()
                self.paused = False
        else:
            self.start_stop(None)
            
    def on_stop(self,w):
        try:
            if self.player:
                self.player.set_state(gst.STATE_NULL)
                self.set_play_play()
                #self._stop_queries()
        except:
            print "Error on Stop"
            
    def on_next(self,w):
        self.cur_index += 1
        if self.cur_index >= self.count:
            self.cur_index = 0
        self.start_stop(None)
        
        
    def on_prev(self,w):
        self.cur_index -= 1
        if self.cur_index < 0:
            self.cur_index = self.count - 1
        self.start_stop(None)
                
    def start_stop(self, path):
        try:
            if not path and self.player:
                path = self.player.get_property('uri')
        except:
            pass

        if path:
            self.player.set_state(gst.STATE_NULL)
            #self.playlbl.set_label("Play")
            self.set_play_pause()
            #print "play:",path
            self.player.set_property('uri', path ) #"file://" + filepath)
            self.player.set_state(gst.STATE_PLAYING)
            #self._start_queries()
            
            self.paused = False
            self.metadata.clear()
            #vol = self.player.get_property("volume")
            #print "Volume:",vol
                
    def convert_ns(self, time_int):
        time_int = time_int / 1000000000
        sec = time_int % 60
        min = time_int % 3600 / 60
        hour = time_int / 3600
        if hour == 0:
            return "%02d:%02d"%(min,sec)
        return "%d:%02d:%02d"%(hour,min,sec)
        
    def destroy(klass, widget=None):
        gtk.main_quit()
        

#from __future__ import with_statement
import sys,linecache
def traceit(frame, event, arg):
    if event == "line":
        lineno = frame.f_lineno
        filename = frame.f_globals["__file__"]
        if filename == "<stdin>":
            filename = "glade.py"
        if (filename.endswith(".pyc") or
            filename.endswith(".pyo")):
            filename = filename[:-1]
        name = frame.f_globals["__name__"]
        line = linecache.getline(filename, lineno)
        print "%s:%s: %s" % (name, lineno, line.rstrip())

    return traceit
    
if __name__ == "__main__":
    #sys.settrace(traceit)
    g = Gui()
    gtk.main()
